﻿using AutoMapper;
using Grpc.Core;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Windows.Admin.Application.Service;
using Windows.Admin.Application.Service.User.Dtos;
using Windows.Admin.Contract;
using Windows.Admin.Domain;
using Windows.Admin.Infrastructure.EFCore;
using Windows.Admin.Infrastructure.EFCore.Extensions;
using Windows.Application.Share;
using Windows.FileStorage.Contract;
using Windows.Infrastructure.Share.Extensions;
using Windows.Infrastructure.Share.Security;

namespace Windows.Admin.Application
{
    public class UserService : IUserService
    {
        private readonly IMapper _mapper;
        private readonly ICurrentUser _currentUser;
        private readonly AdminDbContext _db;
        private readonly IAttachmentGrpcService _attachmentGrpcSvc;
        public UserService(IMapper mapper,  AdminDbContext db, IAttachmentGrpcService attachmentGrpcSvc, ICurrentUser currentUser)
        {
            _mapper = mapper;
            _db = db;
            _attachmentGrpcSvc = attachmentGrpcSvc;
            _currentUser = currentUser;
        }
        /// <summary>
        /// 获取当前登录用户详情(基本信息)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<CurrentUserResponse> CurrentUser()
        {
            var model = await _db.User.Include(x => x.Employees).FindByIdAsync(_currentUser.Id);
            var res = _mapper.Map<CurrentUserResponse>(model);
            res.Name = res.UserName;
            if (model!.Employees!.Any())
            {
                var employee = model!.Employees!.FirstOrDefault();
                res.EmployeeId = employee!.Id;
                res.Name = employee.Name;
                AttachmentRequest request = new()
                {
                    OwnerId = res.EmployeeId
                };
                var attachment = await _attachmentGrpcSvc.GetAttachment(request);
                res.AttachmentPath = attachment.AttachmentPath;
            }
            return res;
        }
        /// <summary>
        /// 获取全部用户
        /// </summary>
        /// <returns></returns>
        public async Task<List<UserResponse>> GetUsers()
        {
            var users = await _db.User.ToListAsync();
            return _mapper.Map<List<UserResponse>>(users);
        }
        /// <summary>
        /// 用户页面
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResponse<UserResponse>> Query(PageRequest<UserRequest> request)
        {
            var response = new PageResponse<UserResponse>();
            IQueryable<User> query = _db.User.Include(x=>x.Role_Users);
            if (!request.Query.UserName.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.UserName.Contains(request.Query.UserName!));
            }
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();

            var roles = await (from a in _db.Role
                               from b in a.Role_Users!
                               where list.Select(s => s.Id).ToList().Contains(b.UserId)
                               select a).Distinct().ToListAsync();
            var userResponses = _mapper.Map<List<UserResponse>>(list);
            foreach (var u in userResponses)
            {
                u.RoleNames = roles.Where(x => u.RoleIds!.Contains(x.Id)).Select(s => s.Name).ToList();
            }
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = userResponses;
            return response;
        }
        /// <summary>
        /// 获取id的用户详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserResponse> Detail(int id)
        {
            var model = await _db.User.Include(x=>x.Role_Users).FindByIdAsync(id);
            var response = _mapper.Map<UserResponse>(model);
            response.RoleNames = _db.Role.Where(x => response.RoleIds!.Contains(x.Id)).Select(s => s.Name).ToList();
            return response;
        }
        /// <summary>
        /// 用户保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(UserSaveRequest request)
        {
            if (_db.User.Any(x => x.UserName.ToLower() == request.UserName && x.Id != request.Id))
                throw new ApiException("用户账号已存在!");
            using var tran = _db.Database.BeginTransaction();
            try
            {
                User? model;
                if (request.Id == null)
                {
                    model = _mapper.Map<User>(request);
                    await _db.User.AddAsync(model);
                }
                else
                {
                    model = await _db.User.FindByIdAsync(request.Id.Value);
                    if (model == null)
                        throw new ApiException("用户不存在!");
                    model.UserName = request.UserName;
                    model.Password = request.Password;
                    model.Remark = request.Remark;
                }
                await _db.SaveChangesAsync();
                var roleUsers = await _db.Role_User.Where(x => x.UserId == model.Id).ToListAsync();
                _db.RemoveRange(roleUsers);
                if (request.RoleIds != null)
                {
                    foreach (long roleId in request.RoleIds)
                    {
                        Role_User role_User = new()
                        {
                            RoleId = roleId,
                            UserId = model.Id
                        };
                        await _db.Role_User.AddAsync(role_User);
                    }
                }
                await _db.SaveChangesAsync();
                await tran.CommitAsync();
            }
            catch (Exception)
            {
                await tran.RollbackAsync();
                throw;
            }
        }
        /// <summary>
        /// 获取所有可聊天的用户
        /// </summary>
        /// <returns></returns>
        public async Task<List<ChatUserResponse>> GetChatUsers()
        {
            var users = await _db.User.Include(x => x.Employees).ToListAsync();
            return _mapper.Map<List<ChatUserResponse>>(users);
        }
        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="info"></param>
        /// <param name="isEnable"></param>
        /// <returns></returns>
        //public async Task<PageResponse<UserResponse>> Query(PageRequest<UserRequest> info)
        //{
        //    using (var db = NewDB())
        //    {
        //        PageResponse<UserResponse> model = new PageResponse<UserResponse>();
        //        var query = db.User.AsNoTracking().Where(x => x.Id != AppSetting.SystemConfig.Admin.ToGuid());
        //        var organizations = await db.Organization.AsNoTracking().ToListAsync();
        //        var organizationDtos = _mapper.Map<List<OrganizationResponse>>(organizations);
        //        if (!info.Query.OrganizationId.IsEmpty())
        //        {
        //            List<object> ids = new List<object>();
        //            GetCurrentAndChildrenIds(organizationDtos, ids, info.Query.OrganizationId.ToString(), true);
        //            query = query.GetByOrganizationIds(ids.Select(s => s.ToGuid()).ToArray());
        //        }
        //        if (!info.Query.Name.IsNullOrEmpty())
        //            query = query.Where(x => x.Name.Contains(info.Query.Name));
        //        if (!info.Query.UserName.IsNullOrEmpty())
        //            query = query.Where(x => x.UserName.Contains(info.Query.UserName));
        //        if (info.Query.CreatedOnStart != null)
        //            query = query.Where(x => x.CreatedOn >= info.Query.CreatedOnStart);
        //        if (info.Query.CreatedOnEnd != null)
        //            query = query.Where(x => x.CreatedOn <= info.Query.CreatedOnEnd);

        //        int totalCount = await query.CountAsync();
        //        List<User> list = await query.OrderBy(x => x.CreatedOn).Paging(info.PageIndex, info.PageSize).Include(x => x.Organization_User).ToListAsync();
        //        User user = new User();
        //        model.PageIndex = info.PageIndex;
        //        model.PageSize = info.PageSize;
        //        model.TotalCount = totalCount;
        //        model.List = _mapper.Map<List<UserResponse>>(list);
        //        foreach (var l in model.List)
        //        {
        //            if (l.OrganizationIds == null)
        //                continue;
        //            foreach (var organizationId in l.OrganizationIds)
        //            {
        //                string organizationName = "";
        //                List<OrganizationResponse> outList = new List<OrganizationResponse>();
        //                var organization = organizationDtos.FirstOrDefault(x => x.Id.ToGuid() == organizationId);
        //                GetCurrentAndParents(organizationDtos, outList, organization);
        //                foreach (var obj in outList)
        //                {
        //                    organizationName = obj.Name + "-" + organizationName;
        //                }
        //                if (organizationName.Length > 0)
        //                    l.OrganizationNames.Add(organizationName.Trim('-'));
        //            }
        //        }
        //        return model;
        //    }
        //}
        /// <summary>
        /// 根据角色Id获取用户列表
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        //public async Task<List<UserResponse>> GetRoleUsers(Guid roleId)
        //{
        //    using (var db = NewDB())
        //    {
        //        var users = await (from a in db.User
        //                           join b in db.Role_User on a.Id equals b.UserId
        //                           where b.RoleId == roleId
        //                           select a).ToListAsync();
        //        return _mapper.Map<List<UserResponse>>(users);
        //    }
        //}
        /// <summary>
        /// 根据id获取user
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        //public async Task<UserResponse> Detail(Guid id)
        //{
        //    using (var db = NewDB())
        //    {
        //        var model = await db.User.Include(x => x.Organization_User).Include(x => x.Role_User).FindByIdAsync(id);
        //        //var organization = await db.Organization.GetByUserId(id).Select(s=>s.Id).ToListAsync();
        //        var dto = _mapper.Map<UserResponse>(model);
        //        var organizations = await db.Organization.AsNoTracking().ToListAsync();
        //        var organizationDtos = _mapper.Map<List<OrganizationResponse>>(organizations);
        //        var roles = await db.Role.Where(x => dto.RoleIds.Contains(x.Id)).ToListAsync();
        //        dto.RoleNames = roles.Select(s => s.Name).ToList();
        //        foreach (var organizationId in dto.OrganizationIds)
        //        {
        //            string organizationName = "";
        //            List<OrganizationResponse> outList = new List<OrganizationResponse>();
        //            var organization = organizationDtos.FirstOrDefault(x => x.Id.ToGuid() == organizationId);
        //            GetCurrentAndParents(organizationDtos, outList, organization);
        //            foreach (var obj in outList)
        //            {
        //                organizationName = obj.Name + "-" + organizationName;
        //            }
        //            if (organizationName.Length > 0)
        //                dto.OrganizationNames.Add(organizationName.Trim('-'));
        //        }
        //        return dto;
        //    }
        //}
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        //public async Task Add(UserAddRequest info)
        //{
        //    using (var db = NewDB())
        //    {
        //        User user = _mapper.Map<User>(info.User);
        //        BeforeAdd(user);
        //        //密码暂写死
        //        user.PassWord = user.UserName;
        //        await db.AddAsync(user);
        //        await db.SaveChangesAsync();
        //        await SetOtherInfo(db, user.Id, info.User.OrganizationIds, info.ModuleIds, info.OperateIds, info.RoleIds);
        //        await db.SaveChangesAsync();
        //    }
        //}
        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        //public async Task Modify(UserModifyRequest info)
        //{
        //    using (var db = NewDB())
        //    {
        //        await db.ExecSqlNoQuery("delete Organization_User where UserId=@UserId", new SqlParameter("UserId", info.Id));
        //        await db.ExecSqlNoQuery("delete Role_User where UserId=@UserId", new SqlParameter("UserId",info.Id));
        //        await db.ExecSqlNoQuery("delete Privilege where MasterValue=@MasterValue", new SqlParameter("MasterValue", info.Id));
        //        var user = await db.User.FindByIdAsync(info.Id);
        //        _mapper.Map(info.User, user);
        //        BeforeModify(user);
        //        await SetOtherInfo(db, info.Id, info.User.OrganizationIds, info.ModuleIds, info.OperateIds, info.RoleIds);
        //        await db.SaveChangesAsync();
        //    }
        //}
        /// <summary>
        /// 更新个人信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        //public async Task ModifyProfile(ProfileRequest info)
        //{
        //    using (var db = NewDB())
        //    {
        //        var user = await db.User.FindByIdAsync(info.Id);
        //        _mapper.Map(info, user);
        //        BeforeModify(user);
        //        await db.SaveChangesAsync();
        //    }
        //}
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        //public async Task ChangePassWord(PassWordRequest info)
        //{
        //    using (var db = NewDB())
        //    {
        //        var user = await db.User.FindByIdAsync(CurrentUser.UserId);
        //        if (info.OldPassWord != user.PassWord)
        //            throw new ApiException("旧密码不正确!");
        //        else if(info.NewPassWord!= info.NewPassWordConfirm)
        //            throw new ApiException("两次输入密码不一致!");
        //        user.PassWord = info.NewPassWord;
        //        BeforeModify(user);
        //        await db.SaveChangesAsync();
        //    }

        //}
        /// <summary>
        /// 设置用户其他关联表信息
        /// </summary>
        /// <param name="db"></param>
        /// <param name="userId"></param>
        /// <param name="moduleIds"></param>
        /// <param name="operateIds"></param>
        /// <param name="roleIds"></param>
        /// <returns></returns>
        //private async Task SetOtherInfo(JyzContext db,Guid userId,List<Guid> organizationIds, List<Guid> moduleIds, List<Guid> operateIds, List<Guid> roleIds)
        //{
        //    foreach (Guid id in organizationIds)
        //    {
        //        Organization_User ou = new Organization_User()
        //        {
        //            UserId = userId,
        //            OrganizationId = id
        //        };
        //        await db.AddAsync(ou);
        //    }
        //    foreach (Guid id in moduleIds)
        //    {
        //        Privilege privilege = new Privilege(MasterEnum.User, userId, AccessEnum.Module, id);
        //        await db.AddAsync(privilege);
        //    }
        //    foreach (Guid id in operateIds)
        //    {
        //        Privilege privilege = new Privilege(MasterEnum.User, userId, AccessEnum.Operate, id);
        //        await db.AddAsync(privilege);
        //    }
        //    foreach (Guid id in roleIds)
        //    {
        //        Role_User model = new Role_User();
        //        model.UserId = userId;
        //        model.RoleId = id;
        //        await db.AddAsync(model);
        //    }
        //}
    }
}
